import { Component, OnInit, OnDestroy } from '@angular/core'
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms'
import { I18NService } from '@core'
import { NzMessageService } from 'ng-zorro-antd'
import { tap, take, takeUntil } from 'rxjs/operators'

import { NewPageAccessor } from '@shared/components/new-page/new-page.interface'
import { Currency, ECurrencyDecimal } from '@shared/interfaces/common'
import { IManualAuthCollection } from '@shared/interfaces/manualAuth'
import { makeAllControlDirty } from 'app/utils/helpers'
import { ManualAuthDataService } from '../../manual-auth-data.service'
import {
  CVV2Length,
  onlyNumberReg,
  ManualAuthAcctNumMinLength,
  ManualAuthAcctNumMaxLength,
  ManualAuthTransAmtMaxValue
} from 'app/utils/contraints'
import { BehaviorSubject, Subject } from 'rxjs'

@Component({
  selector: 'app-manual-auth-new',
  templateUrl: './manual-auth-form.component.html',
  styleUrls: ['../../../../../shared/styles/new-page-form.less'],
})
export class ManualAuthNewFormComponent implements NewPageAccessor, OnInit, OnDestroy {
  constructor(
    private fb: FormBuilder,
    private msg: NzMessageService,
    private i18n: I18NService,
    private dataService: ManualAuthDataService,
  ) {}

  data: any
  payload: IManualAuthCollection
  errorTips = {}
  collectionData: IManualAuthCollection

  form: FormGroup = this.fb.group({})
  // 页面引用
  transAmtMaxValue = ManualAuthTransAmtMaxValue

  private _decimal$ = new BehaviorSubject<number>(0)
  decimal$ = this._decimal$.asObservable()
  private _amtMinValue$ = new BehaviorSubject<number>(1)
  amtMinValue$ = this._amtMinValue$.asObservable()
  destroy$ = new Subject()

  get currencyCtrl(): FormControl {
    return this.form.get('currency') as FormControl
  }

  ngOnInit() {
    this.dataService.manualAuthData$.value$
      .pipe(
        tap(data => {
          this.collectionData = data
          this.initColumn(data)
          this.initErrorTips()
          this.currencyCtrl.valueChanges.pipe(
            takeUntil(this.destroy$),
            tap((value: Currency) => {
              this._decimal$.next( value ? value.decimal : 0)
              switch (value.decimal) {
                case ECurrencyDecimal.TWO:
                  this._amtMinValue$.next(0.01)
                  break
                case ECurrencyDecimal.ZERO:
                default:
                  this._amtMinValue$.next(1)
                  return
              }

            })
          ).subscribe()
        }),
        take(1),
      )
      .subscribe()
  }

  ngOnDestroy(): void {
    this.destroy$.next()
    this.destroy$.complete()
  }

  checkValid(): boolean {
    if (this.form.valid) {
      this.pushDataToStore()
      this.msg.success(this.trans('GENERAL.NOTIFICATION.VALIDATION_SUCCESS'))
      return true
    }

    makeAllControlDirty(this.form)
    return false
  }

  pushDataToStore(): void {
    const currency = this.form.get('currency').value
    const data: IManualAuthCollection = {
      insCode: this.collectionData.insCode,
      intStoreCode: this.collectionData.intStoreCode,
      transAmt: this.form.get('transAmt').value,
      currency: currency && currency.code,
      currencyAll: currency,
      acctNum: this.form.get('acctNum').value,
      effectiveDate: this.form.get('effectiveDate').value,
      cvv2: this.form.get('cvv2').value,
    }

    this.payload = data
    this.dataService.setManualAuthData(Object.assign(this.collectionData, data))
  }

  private trans(key: string, params?: Object): string {
    return this.i18n.fanyi(key, params)
  }

  private initColumn(data: IManualAuthCollection): void {
    const { transAmt, currencyAll, acctNum, effectiveDate, cvv2 } = data
    let currency: Currency
    if (currencyAll) {
      currency = new Currency()
      currency.code = currencyAll.code
      currency.name = currencyAll.name
    }
    this.form = this.fb.group({
      transAmt: [transAmt, [Validators.required]],
      currency: [currency, [Validators.required]],
      acctNum: [acctNum, [
        Validators.required,
        Validators.minLength(ManualAuthAcctNumMinLength),
        Validators.maxLength(ManualAuthAcctNumMaxLength),
        Validators.pattern(onlyNumberReg),
      ]],
      effectiveDate: [effectiveDate, [Validators.required]],
      cvv2: [cvv2, [
        Validators.required,
        Validators.minLength(CVV2Length),
        Validators.maxLength(CVV2Length),
        Validators.pattern(onlyNumberReg),
      ]],
    })
  }

  private initErrorTips() {
    this.errorTips = {
      transAmt: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('OPERATION.MANUAL_AUTH.TRANS_AMT') }),
      },
      currency: {
        required: this.trans('VALIDATION.REQUIRED_SELECT', { name: this.trans('OPERATION.MANUAL_AUTH.TRANS_CURRENCY') }),
      },
      acctNum: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('OPERATION.MANUAL_AUTH.ACCT_NUM') }),
        minlength: this.trans('VALIDATION.MIN_LENGTH', { length: ManualAuthAcctNumMinLength }),
        maxlength: this.trans('VALIDATION.MAX_LENGTH', { length: ManualAuthAcctNumMaxLength }),
        pattern: this.trans('VALIDATION.PATTERN.NUMBER_ONLY'),
      },
      effectiveDate: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('OPERATION.MANUAL_AUTH.EFFECTIVE_DATE') }),
      },
      cvv2: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('OPERATION.MANUAL_AUTH.CVV2') }),
        minlength: this.trans('VALIDATION.FIXED_LENGTH_NUM', { length: CVV2Length }),
        maxlength: this.trans('VALIDATION.FIXED_LENGTH_NUM', { length: CVV2Length }),
        pattern: this.trans('VALIDATION.PATTERN.NUMBER_ONLY'),
      },
    }
  }
}
